/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/*
 * BarGraphPanel.java
 *
 * Created on Aug 3, 2009, 11:18:54 AM
 */
package GraphPackage;

import GUIUtilities.ColorUtilities;
import GUIUtilities.LabelManager;
import LabelPanelPackage.LabelPanel;
import java.awt.Color;
import java.awt.Dimension;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.Vector;
import javax.swing.JLabel;

/**
 *
 * @author Heather
 */
public class CCPVGraphPanel extends javax.swing.JPanel
{
  // NEED DIFFERENT CONSTRUCTOR FOR LINE GRAPHS!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

  public CCPVGraphPanel(GraphTypes type, Vector<CCPVGraphMember> members)
  {
    initComponents();
    this.type = type;
    this.members = members;
    if (type == GraphTypes.horizontal)
    {
      displayGraph = new HorizontalBarGraph(members.size());
    }
    else if (type == GraphTypes.vertical)
    {
      displayGraph = new VerticalBarGraph(members.size());
    }
    else if (type == GraphTypes.line)
    {
      displayGraph = new LineGraph();
    }

    displayGraph.setLocation(0, 0);
    displayGraph.setSize(new Dimension(defaultWidth, defaultHeight));
    displayGraph.setPreferredSize(new Dimension(defaultWidth, defaultHeight));
    graphContainer.add(displayGraph);
    Dimension lpD = new Dimension(250, 510);
    lp.setBackground(Color.white);
    lp.setScaleTo(lpD);
    labelsContainer.setViewportView(lp);
  }

  public CCPVGraphPanel(GraphTypes type, Vector<CCPVGraphMember> members, double maxValue, double minValue, double increment)
  {
    initComponents();
    this.type = type;
    this.members = members;
    if (type == GraphTypes.horizontal)
    {
      displayGraph = new HorizontalBarGraph(members.size());
    }
    else if (type == GraphTypes.vertical)
    {
      displayGraph = new VerticalBarGraph(members.size(), maxValue, minValue, increment);
    }
    else if (type == GraphTypes.line)
    {
      displayGraph = new LineGraph();
    }

    displayGraph.setLocation(0, 0);
    displayGraph.setSize(new Dimension(defaultWidth, defaultHeight));
    displayGraph.setPreferredSize(new Dimension(defaultWidth, defaultHeight));
    graphContainer.add(displayGraph);
    Dimension lpD = new Dimension(250, 510);
    lp.setBackground(Color.white);
    lp.setScaleTo(lpD);
    labelsContainer.setViewportView(lp);
  }

  /** Creates new form BarGraphPanel */
  public CCPVGraphPanel()
  {
    initComponents();
    graphContainer.setPreferredSize(new Dimension(defaultWidth, defaultHeight));
    graphContainer.setSize(new Dimension(defaultWidth, defaultHeight));
    graphContainer.add(theVerticalBarGraph);
    //graphContainer.add(theLineGraph);
    //graphContainer.add(theHorizontalBarGraph);
    System.out.println("component 0 size: " + graphContainer.getComponent(0).getSize());


    theLineGraph.setLocation(0, 0);
    theLineGraph.setSize(new Dimension(defaultWidth, defaultHeight));
    theLineGraph.setPreferredSize(new Dimension(defaultWidth, defaultHeight));
    theLineGraph.addRandomLine();
    //theLineGraph.addRandomLine();
    //theLineGraph.addRandomLine();
    theLineGraph.repaint();


    theVerticalBarGraph.setLocation(0, 0);
    theVerticalBarGraph.setSize(new Dimension(defaultWidth, defaultHeight));
    theVerticalBarGraph.setPreferredSize(new Dimension(defaultWidth, defaultHeight));
    theVerticalBarGraph.setRandomBarValues();
    theVerticalBarGraph.setRandomBarColors();
    theVerticalBarGraph.repaint();

    theHorizontalBarGraph.setLocation(0, 0);
    theHorizontalBarGraph.setSize(new Dimension(defaultWidth, defaultHeight));
    theHorizontalBarGraph.setPreferredSize(new Dimension(defaultWidth, defaultHeight));
    theHorizontalBarGraph.setRandomBarValues();
    theHorizontalBarGraph.setRandomBarColors();
    theHorizontalBarGraph.repaint();

    // set the labels panel
    setupLabels();
    labelsContainer.setViewportView(lp);
  }

  public void setupLabels()
  {
    Set<CCPVGraphMember> keys;
    Iterator<CCPVGraphMember> keyIt = null;

    if (type == GraphTypes.horizontal)
    {
      keys = barValues.keySet();
      keyIt = keys.iterator();
    }
    else if (type == GraphTypes.vertical)
    {
      keys = barValues.keySet();
      keyIt = keys.iterator();
    }
    else if (type == GraphTypes.line)
    {
      // NOT DOING LINES!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    }

    while (keyIt.hasNext())
    {
      CCPVGraphMember member = keyIt.next();
      JLabel newLabel = new JLabel(member.name);
      newLabel.setOpaque(true);
      Vector<Integer> polygons = memberToPolygonMap.get(member);
      setupLabelListener(newLabel, member, polygons);
      lp.addLabel(newLabel);

      // change label color
      if ((type == GraphTypes.horizontal) || (type == GraphTypes.vertical))
      {
        int polygon = polygons.get(0);
        Color defaultC = ((BarGraph) displayGraph).getDefaultBarColors().get(polygon);
        newLabel.setBackground(defaultC);
      }
    }
  }

  private void setupLabelListener(final JLabel label, final CCPVGraphMember member, final Vector<Integer> polygons)
  {
    label.addMouseListener(new java.awt.event.MouseAdapter()
    {

      public void mouseClicked(java.awt.event.MouseEvent evt)
      {
      }

      public void mouseEntered(java.awt.event.MouseEvent evt)
      {
        if ((type == GraphTypes.horizontal) || (type == GraphTypes.vertical))
        {
          int polygon = polygons.get(0);
          Color lightened = ColorUtilities.lightenColor(((BarGraph) displayGraph).getDefaultBarColors().get(polygon), 30);
          ((BarGraph) displayGraph).getCurrentBarColors().set(polygon, lightened);
          //System.out.println(polygon);
          label.setBackground(labelHighlight);
          repaint();
          displayGraph.repaint();
        }
        else if (type == GraphTypes.line)
        {
          int polygon = polygons.get(0);
          Color darkened = ColorUtilities.darkenColor(((BarGraph) displayGraph).getColor(polygon), 50);
          //label.setBackground(labelHighlight);
          repaint();
        }
      }

      public void mouseExited(java.awt.event.MouseEvent evt)
      {
        if ((type == GraphTypes.horizontal) || (type == GraphTypes.vertical))
        {
          int polygon = polygons.get(0);
          Color defaultC = ((BarGraph) displayGraph).getDefaultBarColors().get(polygon);
          ((BarGraph) displayGraph).getCurrentBarColors().set(polygon, defaultC);
          label.setBackground(defaultC);
          repaint();
          displayGraph.repaint();
        }
        else if (type == GraphTypes.line)
        {
          int polygon = polygons.get(0);
          repaint();
        }
      }

      public void mousePressed(java.awt.event.MouseEvent evt)
      {
      }

      public void mouseReleased(java.awt.event.MouseEvent evt)
      {
      }
    });
  }

  private void setupHorizontalBars()
  {
    Set<CCPVGraphMember> keys = barValues.keySet();
    Iterator<CCPVGraphMember> keyIt = keys.iterator();
    int index = 0;

    while (keyIt.hasNext())
    {
      CCPVGraphMember member = keyIt.next();
      double value = barValues.get(member);
      ((HorizontalBarGraph) displayGraph).setValue(index, value);
      Vector<Integer> polygons = new Vector<Integer>();
      polygons.add(index);

      memberToPolygonMap.put(member, polygons);
      polygonToMemberMap.put(polygons, member);

      index++;
    }
  }

  private void setupVerticalBars()
  {
    Set<CCPVGraphMember> keys = barValues.keySet();
    Iterator<CCPVGraphMember> keyIt = keys.iterator();
    int index = 0;

    while (keyIt.hasNext())
    {
      CCPVGraphMember member = keyIt.next();
      double value = barValues.get(member);
      ((VerticalBarGraph) displayGraph).setValue(index, value);
      Vector<Integer> polygons = new Vector<Integer>();
      polygons.add(index);

      memberToPolygonMap.put(member, polygons);
      polygonToMemberMap.put(polygons, member);

      index++;
    }
  }

  private void setupLines()
  {
    System.out.println("not doing line graph right now :D");
  }

  public void setupBarValues(HashMap<CCPVGraphMember, Double> barValues)
  {
    if (type == GraphTypes.horizontal)
    {
      this.barValues = barValues;
      setupHorizontalBars();
      setupLabels();
    }
    else if (type == GraphTypes.vertical)
    {
      this.barValues = barValues;
      setupVerticalBars();
      setupLabels();
    }
    else
    {
      throw new IllegalArgumentException("Illegal input for setup bar values.");
    }
  }

  public void setupLineValues(Vector<HashMap<CCPVGraphMember, Double>> lineValues)
  {
    if (type == GraphTypes.line)
    {
      this.lineValues = lineValues;
      setupLines();
      setupLabels();
    }
    else
    {
      throw new IllegalArgumentException("Illegal input for setup bar values.");
    }
  }

  public void setGraphTitle(String newTitle)
  {
    displayGraph.graphTitleLabel.setText(newTitle);
    Dimension labelSize = LabelManager.getLabelDimensions(displayGraph.graphTitleLabel);
    Dimension newLabelSize = new Dimension(labelSize.width + 10, labelSize.height);
    displayGraph.graphTitleLabel.setSize(newLabelSize);
    displayGraph.graphTitleLabel.setPreferredSize(newLabelSize);
    repaint();
  }

  public void setBarNames(List<List<String>> newNames)
  {
    if (displayGraph instanceof BarGraph)
    {
      ((BarGraph)displayGraph).setBarNames(newNames);
    }
  }

  public Vector<CCPVGraphMember> getMembers()
  {
    return members;
  }

  /** This method is called from within the constructor to
   * initialize the form.
   * WARNING: Do NOT modify this code. The content of this method is
   * always regenerated by the Form Editor.
   */
  @SuppressWarnings("unchecked")
  // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
  private void initComponents() {

    graphContainer = new javax.swing.JPanel();
    labelsContainer = new javax.swing.JScrollPane();

    setBackground(new java.awt.Color(255, 255, 204));
    setLayout(null);

    graphContainer.setLayout(null);
    add(graphContainer);
    graphContainer.setBounds(10, 10, 650, 510);
    add(labelsContainer);
    labelsContainer.setBounds(670, 10, 250, 510);
  }// </editor-fold>//GEN-END:initComponents
  // Variables declaration - do not modify//GEN-BEGIN:variables
  private javax.swing.JPanel graphContainer;
  private javax.swing.JScrollPane labelsContainer;
  // End of variables declaration//GEN-END:variables
  // test number set at 10
  private int defaultWidth = 650;
  private int defaultHeight = 510;
  private Graph displayGraph;
  private VerticalBarGraph theVerticalBarGraph = new VerticalBarGraph(15);//, defaultWidth, defaultHeight);
  private HorizontalBarGraph theHorizontalBarGraph = new HorizontalBarGraph(4);//, defaultWidth, defaultHeight);
  private LineGraph theLineGraph = new LineGraph();
  private LabelPanel lp = new LabelPanel();
  private Color labelHighlight = Color.yellow;

  public static enum GraphTypes
  {

    line, vertical, horizontal
  };
  private GraphTypes type = GraphTypes.line;
  private Vector<CCPVGraphMember> members;
  HashMap<CCPVGraphMember, Double> barValues;
  Vector<HashMap<CCPVGraphMember, Double>> lineValues;
  HashMap<CCPVGraphMember, Vector<Integer>> memberToPolygonMap = new HashMap<CCPVGraphMember, Vector<Integer>>();
  HashMap<Vector<Integer>, CCPVGraphMember> polygonToMemberMap = new HashMap<Vector<Integer>, CCPVGraphMember>();
}
